#!/usr/bin/python
'''
/*
 * This computer program is the confidential information and proprietary trade
 * secret of VistaraIT LLC.  Possessions and use of this program must  conform
 * strictly to the license agreement between the user and VistaraIT LLC.,  and
 * receipt or possession does not convey any rights to divulge, reproduce,  or
 * allow others to use this program without specific written authorization  of
 * VistaraIT LLC.
 * 
 * Copyright (c) 2014 VistaraIT, Inc. All rights reserved.
 */
'''

from django.template.loader import render_to_string
import applicationproperties as properties
import logger, time, os, fcntl
from commons import executeCommand, parseUpdateResponse,processTemplateTOFile

class RegisterAppliance():
    
    def __init__(self,appmanager):
        self.appmanager = appmanager
        
        hashArr = {}
        try:
            fin = open(properties.VG_REGISTRATION_FILE, "rb")
            lines = fin.readlines()
            fin.close()
            for line in lines:
                try:
                    if line.startswith("#"):
                        continue
                    keyValues = line.split("=",1)
                    hashArr[keyValues[0]] = keyValues[1].rstrip()
                except:
                    pass
        except:
            pass
        
        self.auth_token = hashArr.get("AUTH_TOKEN","").strip()
        self.server = hashArr.get("MANAGED_SERVER","").strip()
        self.activation_key = hashArr.get("ACTIVATION_KEY","").strip()
        self.alert_url = hashArr.get("ALERT_URL","").strip()
        self.activation_time = hashArr.get("ACTIVATION_TIME","").strip()
    
    def isRegistered(self):
        if self.auth_token != '':
            return True
        return False
    
    def deRegistered(self):
        try:
            self.auth_token = ''
            self.server = ''
            self.activation_key = ''
            self.alert_url = ''
            self.activation_time = ''
            self.saveTofile()
            return True
        except:
            return False
    
    def prepareRegistrationData(self, action, dtype):
        verInfo = self.appmanager.getModuleVersion()
        hdInfo = self.appmanager.getApplianceHardwareInfo()
        return render_to_string('config/registrationrequest.xml', {'appliance':self.appmanager.getApplianceInfo(),'activation_token':self.activation_key,'action':action,'type':dtype,'verInfo':verInfo,'hdInfo':hdInfo})
    
    def getRegistrationInfo(self):
        value = {}
        value["auth_token"] = self.auth_token
        value["cloud_server"] = self.server
        value["activation_key"] = self.activation_key
        value["alert_url"] = self.alert_url
        value["activation_time"] = self.activation_time
        value["is_registered"] = self.isRegistered()
        value["registered_status"] = "Registered" if self.isRegistered() else "Not Registered"
        return value
    
    def getRegistrationHash(self):
        value = {}
        value["AUTH_TOKEN"] = self.auth_token
        value["MANAGED_SERVER"] = self.server
        value["ACTIVATION_KEY"] = self.activation_key
        value["ALERT_URL"] = self.alert_url
        value["ACTIVATION_TIME"] = self.activation_time
        return value
        
    def saveTofile(self):
        self.appmanager.updateFileProperties(properties.VG_REGISTRATION_FILE, self.getRegistrationHash())
        cmd1 = "/usr/bin/sudo chown admin.admin " + properties.VG_REGISTRATION_FILE + " >/dev/null 2>&1"    
        cmd2 = "/usr/bin/sudo chmod 755 " + properties.VG_REGISTRATION_FILE + " >/dev/null 2>&1"
        executeCommand(cmd1,[],True)
        executeCommand(cmd2,[],True)
        
    def activateAppliance(self,server, activation_key):
        if self.isRegistered():
            return True, "Gateway is already activated"
        self.auth_token = ''
        self.server = server
        self.activation_key = activation_key
        self.alert_url = ''
        self.activation_time = ''
        self.saveTofile()
        return self.registerAppliance()
    
    def enableServices(self, filename):
        processTemplateTOFile('config/' + filename, properties.WORK_DIR + filename, {})
        cmd = "/usr/bin/sudo /bin/mv -f " + properties.WORK_DIR + filename + " " + properties.MONITRC_CFG_DIR + filename + " >/dev/null 2>&1"
        executeCommand(cmd, [], True)
        cmd1 = "/usr/bin/sudo chown root.root " + properties.MONITRC_CFG_DIR + filename + " >/dev/null 2>&1"    
        executeCommand(cmd1, [], True)
        cmd2 = "/usr/bin/sudo chmod 700 " + properties.MONITRC_CFG_DIR + filename + " >/dev/null 2>&1"
        executeCommand(cmd2, [], True)
        #os.remove(properties.WORK_DIR + filename)

    
    def activateServicesAtRegistration(self):
        
        cmd = """sudo sed -i -e 's/^gateway.uuid=.*$/gateway.uuid=%s/g' %s""" % (self.auth_token, properties.DISCOVERY_CFG_DEST)
        executeCommand(cmd, [], True)
        
        #services = ['monitoring.monitrc', 'neprobe.monitrc', 'alertd.monitrc','mongodb.monitrc','nodeMgr.monitrc','postgresql.monitrc']
        services = ['monitoring.monitrc', 'neprobe.monitrc', 'nodeMgr.monitrc','postgresql.monitrc']
        for service in services:
            try:
                self.enableServices(service)
            except Exception as emsg:
                logger.logMessage(logger.ERROR,'activateServicesAtRegistration',str(emsg))
            
        cmd = "/usr/bin/sudo /usr/bin/monit reload; sleep 2; /usr/bin/sudo /usr/bin/monit start all"
        result = executeCommand(cmd, [], True)
        if result[0] != 0:
            logger.logMessage(logger.ERROR,'activateServicesAtRegistration',"Failed to reload MONIT service after configuration update.")
            return False
        else:
            logger.logMessage(logger.INFO,'activateServicesAtRegistration',result[1])
        
    
    def registerAppliance(self):
        if self.isRegistered():
            return True, "Gateway is already activated"
        
        if not self.server and not self.activation_key:
            return False, "Could not trigger registration"

        ''' Locking the current file during registration process '''
        cur_file = os.path.abspath(__file__)
        fd = open(cur_file)
        try:
            fileStatus = fcntl.flock(fd, fcntl.LOCK_EX|fcntl.LOCK_NB)
        except:
            logger.logMessage(logger.INFO, 'Registration', 'Another registration request is already processing')
            return False, "Another registration request is already processing"

        registrationData = self.prepareRegistrationData("registration", "cpe")
        logger.logMessage(logger.INFO, 'Registration', 'Prepared registration data')
        response = ""

        url = self.appmanager.toUpdateServerURL(properties.URL_REGISTRATION)
        try:
            status, response = self.appmanager.postXMLData(url,registrationData)
        except Exception as (errno,errmsg):
            if errno == 111:
                logger.logMessage(logger.ERROR, 'Connection Exception', str(errno) + " - " + str(errmsg))
            elif errno == 101:
                logger.logMessage(logger.ERROR, 'Network Exception', str(errno) + " - " + str(errmsg))
            else:
                logger.logMessage(logger.ERROR, 'Caught Exception', str(errno) + " - " + str(errmsg))
            DisplayRegMsg = "Failed to get registration response from the server."
            return False, DisplayRegMsg

        logger.logMessage(logger.INFO, 'Registration', str(status) + " " + str(response))
        if status != 200 or response == "":
            logger.logMessage(logger.ERROR, 'Registration', "Failed to get registration response from the server: " + str(status) + " - " + str(response))
            DisplayRegMsg = "Failed to get registration response from the server."
            return False, DisplayRegMsg

        parseVal = parseUpdateResponse(response, "status");
        
        returnStatus = False
        if parseVal == "valid":
            self.auth_token = parseUpdateResponse(response,"uuId")
            self.alert_url = parseUpdateResponse(response,"alerts_url")
            DisplayRegMsg = properties.AUTO_REG_SUCCESS;
            returnStatus = True
        elif parseVal == "already":
            self.auth_token = parseUpdateResponse(response,"uuId")
            self.alert_url = parseUpdateResponse(response,"alerts_url")
            DisplayRegMsg = properties.AUTO_REG_ALREADY_SUCCESS
            returnStatus = True
        elif parseVal == "invalid":
            self.activation_key = ''
            self.server = ''
            DisplayRegMsg = parseUpdateResponse(response,"errorMessage")
        elif parseVal == "expired":
            self.activation_key = ''
            self.server = ''
            DisplayRegMsg = parseUpdateResponse(response,"errorMessage")
        else:
            self.activation_key = ''
            self.server = ''
            return False, "Got unexpected response"
        
        if self.auth_token != '':
            self.activation_time = time.asctime(time.localtime(time.time()))
            self.activateServicesAtRegistration()
            
            
        self.saveTofile()
        
        logger.logMessage(logger.INFO, 'Registration', DisplayRegMsg)
        return returnStatus, DisplayRegMsg
